package com.bitcs.accesscontrol.log;

import com.bitcs.accesscontrol.service.AccessService;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.*;

/**
 * @author gc
 */
@Aspect
@Component
public class AccessLogAspect {
    @Autowired
    private AccessService accessService;

    ThreadFactory threadFactory = new ThreadFactoryBuilder()
            .setNameFormat("AccessLogAspect-Thread-%d")
            .build();

    ExecutorService executorService = new ThreadPoolExecutor(5, 200, 0L,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024),
            threadFactory,
            new ThreadPoolExecutor.AbortPolicy());

    @Pointcut("@annotation(com.bitcs.accesscontrol.log.AccessLog)")
    public void controllerAspect() {

    }


    @Around("controllerAspect()")
    public String around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
        SaveLogTask saveLogTask = new SaveLogTask(proceedingJoinPoint, httpServletRequest, accessService);
        Future<String> submit = executorService.submit(saveLogTask);
        return submit.get();
    }

}
